/*
 * taskStorge.c
 *  该模块用于动态开启定时电机控制任务和关闭的
 *  Created on: 2025.5.30
 *      Author: TracyHenry
 */
#include "taskStorage.h"
#include "timelist.h"
#include <stdio.h>
#include "w25q16.h"

DEVICE_INFO device_info;
FeedStrategy feedStrategy;
WaterMarkSensorConfigInfo waterMarkSensorConfigInfo;
StaticDataInfo staticDataInfo;
AlarmConfigInfo alarmConfigInfo;
// 定义一个信号量，用于防止多次触发
xQueueHandle taskStorageQueue = NULL;
 // 定义任务句柄，用于管理任务
TaskHandle_t storageTaskHandle = NULL;

uint8_t flag_set_timelist = 0;
uint8_t flag_set_feedstrategy = 0;

/******************************************************************************
 * FunctionName : taskStorgeInit
 * Description  : 存储任务初始化，为了读取存储到存储器中的数据
 * Parameters   : void
 * Returns      : void
*******************************************************************************/
void taskStorgeInit(void)
{
    uint8_t i;
    uint8_t read_data[16],all_buf;
    uint16_t duration_buf;
	  W25Q16_Read(&all_buf,Storage_Num_ADDRESS_Sector, 1);
    printf("all_buf:%d\n",all_buf);
    if(all_buf < 255)
    {
        for ( i = 0; i < all_buf; i++)
        {
            W25Q16_Read(read_data, Storage_TimeList_ADDRESS_Sector + i * 16, 16);
            duration_buf = (((uint16_t)read_data[5]) << 8) | ((uint16_t)read_data[6]);
            insertNode(&timeTable, createNode(read_data[0], read_data[1], read_data[2], read_data[3], read_data[4], duration_buf, read_data[7], read_data[8]));
            printf("Year:%d,Month:%d,Date:%d,Hour:%d,Minute:%d,Duration:%d,speedA:%d,speedB:%d\n",read_data[0],read_data[1],read_data[2],read_data[3],read_data[4],duration_buf,read_data[7],read_data[8]);
        }
    }
    else
    {
        printf("No data in storage!!!\n");
    }

   	W25Q16_Read((uint8_t *)&device_info,Storage_Device_Info_Sector, sizeof(DEVICE_INFO));
    W25Q16_Read((uint8_t *)&feedStrategy,Storage_Feed_Stategy_Info_Sector, sizeof(FeedStrategy));
    W25Q16_Read((uint8_t *)&waterMarkSensorConfigInfo,Storage_WaterMarkSensor_Config_Info_Sector, sizeof(WaterMarkSensorConfigInfo));
    W25Q16_Read((uint8_t *)&staticDataInfo,Storage_StaticData_Info_Sector, sizeof(StaticDataInfo));
    W25Q16_Read((uint8_t *)&alarmConfigInfo,Storage_Alarm_Config_Info_Sector, sizeof(AlarmConfigInfo));
    
}

/******************************************************************************
 * FunctionName : taskStorge
 * Description  : 存储任务
 * Parameters   : void const * argument
 * Returns      : void
*******************************************************************************/
void taskStorge(void const * argument)
{
  /* USER CODE BEGIN taskStorge */
  /* Infinite loop */
     // 初始化信号量
    taskStorageQueue = xQueueCreate(1,sizeof(QueueSetParamEvent));
	QueueSetParamEvent e;
	  uint8_t number_of_table;  
    for(;;)
    {


        if(flag_set_timelist != 0)
         {
            if(flag_set_timelist == 1)
            {
                W25Q16_SectorErase(Storage_TimeList_ADDRESS_Sector);
                W25Q16_SectorErase(Storage_Num_ADDRESS_Sector);
                flag_set_timelist = 2;
            }
            else if(flag_set_timelist == 2)
            {
                traverseListByIndex(timeTable);

                if(timeTableIndex >=  getTableNum())
                {
                        timeTableIndex = 0;
                        flag_set_timelist = 3;
                        //printf("storage timelist complete!!!\n");
                }
                else
                {
                        //printf("timeTableIndex:%d!!!\n",timeTableIndex);
                }

            }
                else if(flag_set_timelist == 3)
            {
                number_of_table = getTableNum();
                W25Q16_PageWrite(&number_of_table,Storage_Num_ADDRESS_Sector, 1);
                flag_set_timelist = 0;
                    printf("storage getTableNum() complete!!!%d\n",number_of_table);
            }
         }
        else if(flag_set_feedstrategy != 0)
        {
            if(flag_set_feedstrategy == 1)
            {
                W25Q16_SectorErase(Storage_Feed_Stategy_Info_Sector);
                flag_set_feedstrategy = 2;
            }
            else if(flag_set_feedstrategy == 2)
            {
                W25Q16_PageWrite( (uint8_t *)&feedStrategy,Storage_Feed_Stategy_Info_Sector,sizeof(FeedStrategy));
                flag_set_feedstrategy = 0;
            }
        }
        else if(xQueueReceive(taskStorageQueue, (void *)&e, portMAX_DELAY) == pdTRUE) 
        {
           switch (e.event)
           {
           case 1:
                if(flag_set_timelist == 0)
                {
                    flag_set_timelist = 1;
                    printf("Triggering taskStorge.\n");
                }
            break;
           case 2:
                storgeByMqtt(e.data, e.len);
            break;
           default:
            break;
           }
        }
        


        osDelay(10);
    }
  /* USER CODE END taskStorge */
}

void storgeByMqtt(uint8_t * data, uint8_t len)
{
    switch (data[0])
    {
    case MQTT_Set_Feed_Base_Param:
        feedStrategy.pigNum = (((uint16_t)data[1]) << 8) | ((uint16_t)data[2]);
        feedStrategy.dayAge = (((uint16_t)data[3]) << 8) | ((uint16_t)data[4]);
        break;
    case MQTT_Set_Operation_Mode:
        feedStrategy.operationMode = data[1];
        break;
    case MQTT_Set_Feed_Mode:
        feedStrategy.feedMode = data[1];
        break;
    case MQTT_Set_LiveStocksFeed_Mode:
        feedStrategy.livestockFeedMode = data[1];
        feedStrategy.waterFeedRatio = (((uint16_t)data[2]) << 8) | ((uint16_t)data[3]);
        break;
    case MQTT_Set_Time_Mode:
        feedStrategy.timeMode = data[1];
        break;
    case MQTT_Set_LiveStockWaterOrder_Mode:
        feedStrategy.waterFeedMode = data[1];
        break;
    case MQTT_Set_IdleWater_Param:
        feedStrategy.idleMode = data[1];
        feedStrategy.feedAndWaterTimeInterval = data[2];
        feedStrategy.waterFeedTimeInterval = data[3];
        feedStrategy.singleMaxWaterFeedAmount = (((uint16_t)data[4]) << 8) | ((uint16_t)data[5]);
        break; 
    case MQTT_Set_CycleFeedTime_Param:
        feedStrategy.startHour = data[1];
        feedStrategy.startMinute = data[2];
        feedStrategy.endHour = data[3];
        feedStrategy.endMinute = data[4];
        feedStrategy.feedCount = data[5];
        break;   
    default:
        break;
    }
    //TODO
    if(flag_set_feedstrategy == 0)
    {
        flag_set_feedstrategy = 1;
    }

}
